home *** CD-ROM | disk | FTP | other *** search
- /* $Id: cbheader.c,v 1.1.1.1 1993/06/21 11:11:59 anjo Exp $
- *
- * File cbheader.c
- * Part of ChessBase utilities file format (CBUFF)
- * Author Anjo Anjewierden, anjo@swi.psy.uva.nl
- * Purpose Representation of game header
- * Works with GNU CC 2.4.5
- *
- * Notice Copyright (c) 1993 Anjo Anjewierden
- *
- * History 09/06/93 (Created)
- * 03/11/93 (Last modified)
- */
-
-
- /*------------------------------------------------------------
- * Directives
- *------------------------------------------------------------*/
-
- #include "cbuff.h"
-
-
- /*------------------------------------------------------------
- * Initialisation
- *------------------------------------------------------------*/
-
- CbHeader
- newCbHeader()
- { CbHeader ch;
-
- ch = alloc(sizeof(struct cbheader));
- resetCbHeader(ch);
- return ch;
- }
-
-
- void
- freeCbHeader(CbHeader ch)
- { unalloc(ch);
- }
-
-
- void
- resetCbHeader(CbHeader ch)
- { ch->year = 0;
- ch->result = 0;
- ch->movesLength = 0;
- ch->playersLength = 0;
- ch->sourceLength = 0;
- ch->commentLength = 0;
- ch->whiteElo = 0;
- ch->blackElo = 0;
- ch->flags1 = 0;
- ch->flags2 = 0;
- ch->moves = 0;
- ch->checksum = 0;
- }
-
-
- void
- initCbHeader(CbHeader ch, unsigned char *h)
- { unsigned char k;
- int i;
-
- /* Unscramble the header.
- */
- k = 101;
- for (i=13; i>=0; i--)
- { h[i] ^= k;
- k *= 3;
- }
-
-
- /* Manual copy to ensure possible differences
- * in machine dependent byte order are handled correctly.
- * (Suggested by Anders Thulin, ath@linkoping.trab.se).
- */
- ch->year = h[0];
- ch->result = h[1];
- ch->movesLength = (h[2] << 8) | h[3];
- ch->playersLength = h[4];
- ch->sourceLength = h[5];
- ch->commentLength = (h[6] << 8) | h[7];
- ch->whiteElo = h[8];
- ch->blackElo = h[9];
- ch->flags1 = h[10];
- ch->flags2 = h[11];
- ch->moves = h[12];
-
- ch->checksum = INCORRECT_CHECKSUM;
-
- if ( ((h[0] * 0x25 + h[5] + h[9]) & 0xff) == h[13]
- || ((h[3] * 0x1ec1 * (h[8]+1) * h[0]) & 0xff) == h[13])
- ch->checksum = CORRECT_CHECKSUM;
- #if PROTECTED_GAMES
- # include protect.h
- #endif
- ch->flags2 ^= 14 + (h[4] & 63) + (h[5] & 63);
- /*
- ch->flags2 ^= 14 + (playersLengthCbHeader(ch) & 63)
- + (sourceLengthCbHeader(ch) & 63);
- */
- }
-
-
- /*------------------------------------------------------------
- * Extracting information
- *------------------------------------------------------------*/
-
- bool
- fullGameCbHeaderP(CbHeader ch)
- { if ((ch->flags1 & FULL_GAME_MASK) == 0)
- return TRUE;
- return FALSE;
- }
-
-
- bool
- deletedCbHeaderP(CbHeader ch)
- { if ((ch->flags1 & GAME_DELETED_MASK))
- return TRUE;
- return FALSE;
- }
-
-
- bool
- markedCbHeaderP(CbHeader ch)
- { if ((ch->flags1 & GAME_MARKED_MASK))
- return TRUE;
- return FALSE;
- }
-
-
- int
- yearCbHeader(CbHeader ch)
- { if (ch->year == YEAR_UNKNOWN)
- return 0;
- return 1900 + ch->year;
- }
-
-
- int
- whiteEloCbHeader(CbHeader ch)
- { return (ch->whiteElo ? 1600+5*(int) ch->whiteElo : 0);
- }
-
-
- int
- blackEloCbHeader(CbHeader ch)
- { return (ch->blackElo ? 1600+5*(int) ch->blackElo : 0);
- }
-
-
- int
- movesLengthCbHeader(CbHeader ch)
- { return ch->movesLength - 1;
- }
-
-
- int
- playersLengthCbHeader(CbHeader ch)
- { return ch->playersLength & PLAYERS_MASK;
- }
-
-
- int
- sourceLengthCbHeader(CbHeader ch)
- { return ch->sourceLength & SOURCE_MASK;
- }
-
-
- int
- commentLengthCbHeader(CbHeader ch)
- { return ch->commentLength;
- }
-
-
- int
- movesCbHeader(CbHeader ch)
- { return ch->moves;
- }
-
-
- char *
- ecoCbHeader(CbHeader ch)
- { static char eco[7];
- unsigned int eco1;
- unsigned int eco2;
-
- if (!fullGameCbHeaderP(ch))
- { eco[0] = '\0';
- return eco;
- }
-
- eco1 = ( ((ch->playersLength & ECO_PART1_MASK) >> 1)
- | ((ch->sourceLength & ECO_PART2_MASK) << 1)
- | ((ch->flags1 & ECO_PART3_MASK) >> 1)
- );
- eco2 = ( (ch->flags2 & ECO2_PART1_MASK)
- | ((ch->flags2 & ECO2_PART2_MASK) >> 1)
- );
- eco[0] = '\0';
-
- if (eco1)
- { if (eco2)
- sprintf(eco, "%c%02d/%02d", 65+(eco1-1)/100, (eco1-1)%100, eco2);
- else
- sprintf(eco, "%c%02d", 65+(eco1-1)/100, (eco1-1)%100);
- }
-
- return eco;
- }
-
-
- bool
- flags2bit6CbHeader(CbHeader ch)
- { return (ch->flags2 & 0x40 ? TRUE : FALSE);
- }
-
-
- void
- decodeCbHeader(CbHeader ch)
- { if (!fullGameCbHeaderP(ch))
- { printf("Game has a starting position\n");
- return;
- }
- printf("Year: %d\n", yearCbHeader(ch));
- printf("Result: %d\n", ch->result);
- printf("Move length: %d\n", movesLengthCbHeader(ch));
- printf("Players length: %d\n", playersLengthCbHeader(ch));
- printf("Source length: %d\n", sourceLengthCbHeader(ch));
- printf("Comment length: %d\n", commentLengthCbHeader(ch));
- printf("White ELO: %d\n", whiteEloCbHeader(ch));
- printf("Black ELO: %d\n", blackEloCbHeader(ch));
- printf("Flags 1: %x\n", ch->flags1);
- printf("Flags 2: %x\n", ch->flags2);
- printf("Moves: %d\n", ch->moves);
- printf("Checksum: %x\n", ch->checksum);
- }
-
-
- /*------------------------------------------------------------
- * Setting information
- *------------------------------------------------------------*/
-
- void
- setYearCbHeader(CbHeader ch, int year)
- { ch->year = (year == 0 ? YEAR_UNKNOWN : 1900 - year);
- }
-
-
- void
- setWhiteEloCbHeader(CbHeader ch, int elo)
- { ch->whiteElo = (elo <= 1600 ? 0 : (elo - 1600) / 5);
- }
-
-
- void
- setBlackEloCbHeader(CbHeader ch, int elo)
- { ch->blackElo = (elo <= 1600 ? 0 : (elo - 1600) / 5);
- }
-